﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Globalization;

namespace Estimador_EDAL.Interface_View
{
    public partial class DiagramView : Form
    {
        private double m_Zoom;
        private Bitmap m_ImagemOriginal;
        private CDiagramDataCollection m_DataCollection;

        private bool m_ImprimeDadosDataCollection = true;
        private bool m_ImprimeValidacaoDataCollection = true;

        #region Construção do Objeto

        public DiagramView(double zoom = 1.00, Bitmap imagemOriginal = null, CDiagramDataCollection dataCollection = null)
        {
            InitializeComponent();

            this.SetStyle(ControlStyles.AllPaintingInWmPaint |
                            ControlStyles.UserPaint |
                            ControlStyles.ResizeRedraw |
                            ControlStyles.UserPaint |
                            ControlStyles.DoubleBuffer, true);
            m_Zoom = zoom;
            m_ImagemOriginal = imagemOriginal;
            m_DataCollection = dataCollection;
            UpdateImagem();
        }

        public void CarregaDataCollectionDeArquivo(string fileName, ref string repDados, ref string repValida)
        {
            m_DataCollection = new CDiagramDataCollection();

            CultureInfo formatProvider = (CultureInfo)CultureInfo.InvariantCulture.Clone();
            string str_Data = System.IO.File.ReadAllText(fileName);
            m_DataCollection.CarregaDeTxt(str_Data);

            if ((m_ImprimeDadosDataCollection) && (repDados != null)) repDados += m_DataCollection.DescarregaParaTxt(repDados == "");
            if ((m_ImprimeValidacaoDataCollection) && (repValida != null)) repValida += m_DataCollection.ValidaDados(repValida == "");
        }

        private void pictureBoxView_Paint(object sender, PaintEventArgs e)
        {
            if (m_DataCollection == null)
                return;

            Graphics g = e.Graphics;
            Font drawFont = new Font("Courier New", 8);

            foreach (CDiagramData data in m_DataCollection.ListDiagramData)
            {
                SizeF extend = new SizeF();

                Pen aPenMed = new Pen(Color.GreenYellow);
                g.DrawRectangle(aPenMed, (float)(data.Xmed * m_Zoom), (float)(data.Ymed * m_Zoom), (int)(80.0f * m_Zoom), (int)(14.0f * m_Zoom));

                Size sizeMed = new Size((int)(80.0f * m_Zoom), (int)(14.0f * m_Zoom));
                Font drawFontMed = AppropriateFont(g, 1, 50, sizeMed, "Vmed = xxxx", drawFont, out extend);
                SolidBrush drawBrushMed = new SolidBrush(Color.GreenYellow);
                g.DrawString("Vmed = xxxx", drawFontMed, drawBrushMed, (float)(data.Xmed * m_Zoom), (float)(data.Ymed * m_Zoom));

                Pen aPenEst = new Pen(Color.DeepSkyBlue);
                g.DrawRectangle(aPenEst, (float)(data.Xest * m_Zoom), (float)(data.Yest * m_Zoom), (int)(80.0f * m_Zoom), (int)(14.0f * m_Zoom));

                Size sizeEst = new Size((int)(80.0f * m_Zoom), (int)(14.0f * m_Zoom));
                Font drawFontEst = AppropriateFont(g, 1, 50, sizeEst, "Vest = yyyy", drawFont, out extend);
                SolidBrush drawBrushEst = new SolidBrush(Color.DeepSkyBlue);
                g.DrawString("Vest = yyyy", drawFontEst, drawBrushEst, (float)(data.Xest * m_Zoom), (float)(data.Yest * m_Zoom));
            }
        }

        public Font AppropriateFont(Graphics g, float minFontSize, float maxFontSize, Size layoutSize, string s, Font f, out SizeF extent)
        {
            if (maxFontSize == minFontSize)
                f = new Font(f.FontFamily, minFontSize, f.Style);

            extent = g.MeasureString(s, f);

            if (maxFontSize <= minFontSize)
                return f;

            float hRatio = layoutSize.Height / extent.Height;
            float wRatio = layoutSize.Width / extent.Width;
            float ratio = (hRatio < wRatio) ? hRatio : wRatio;

            float newSize = f.Size * ratio;

            if (newSize < minFontSize) newSize = minFontSize;
            else if (newSize > maxFontSize) newSize = maxFontSize;

            f = new Font(f.FontFamily, newSize, f.Style);
            extent = g.MeasureString(s, f);

            return f;
        }

        #endregion Construção do Objeto

        #region Get's e Set's

        //[Membro com acesso Externo] Zoom a ser aplicado em Image.
        public double Zoom
        {
            get { return m_Zoom; }
            set
            {
                m_Zoom = (value < 0.01) ? 0.01 : value;
                UpdateImagem();
            }
        }

        //[Membro com acesso Externo] Imagem a ser mostrada no Form.
        public Bitmap ImagemOriginal
        {
            get { return m_ImagemOriginal; }
            set
            {
                m_ImagemOriginal = value;
                UpdateImagem();
            }
        }

        public bool ImprimeDadosDataCollection
        {
            get { return m_ImprimeDadosDataCollection; }
            set { if (m_ImprimeDadosDataCollection != value) m_ImprimeDadosDataCollection = value; }
        }

        public bool ImprimeValidacaoDataCollection
        {
            get { return m_ImprimeValidacaoDataCollection; }
            set { if (m_ImprimeValidacaoDataCollection != value) m_ImprimeValidacaoDataCollection = value; }
        }

        private void UpdateImagem()
        {
            if (m_ImagemOriginal == null)
            {
                this.pictureBoxView.Image = null;
                this.pictureBoxView.Width = this.ClientRectangle.Width;
                this.pictureBoxView.Height = this.ClientRectangle.Height;
            }
            else
            {
                Size sz = new Size((int)(m_Zoom * m_ImagemOriginal.Width), (int)(m_Zoom * m_ImagemOriginal.Height));
                this.pictureBoxView.Image = new Bitmap(m_ImagemOriginal, sz);
                this.pictureBoxView.Width = this.pictureBoxView.Image.Width;
                this.pictureBoxView.Height = this.pictureBoxView.Image.Height;
            }
        }

        #endregion Get's e Set's

        #region Eventos do Menu de Contexto

        private void toolStripItem_10_Click(object sender, EventArgs e) { Zoom = 0.10; }
        private void toolStripItem_25_Click(object sender, EventArgs e) { Zoom = 0.25; }
        private void toolStripItem_50_Click(object sender, EventArgs e) { Zoom = 0.50; }
        private void toolStripItem_75_Click(object sender, EventArgs e) { Zoom = 0.75; }
        private void toolStripItem_100_Click(object sender, EventArgs e){ Zoom = 1.00; }
        private void toolStripItem_150_Click(object sender, EventArgs e){ Zoom = 1.50; }
        private void toolStripItem_200_Click(object sender, EventArgs e){ Zoom = 2.00; }
        private void toolStripItem_400_Click(object sender, EventArgs e){ Zoom = 4.00; }

        #endregion Eventos do Menu de Contexto

        #region Eventos de Mouse

        private Point pointMouseDown = Point.Empty;

        private void DiagramView_MouseDown(object sender, MouseEventArgs e)
        {
            pointMouseDown = e.Location;
            this.Cursor = Cursors.Hand;
        }

        private void DiagramView_MouseUp(object sender, MouseEventArgs e)
        {
            if (pointMouseDown != Point.Empty)
            {
                Point pointMouseUp = e.Location;

                int dx = pointMouseDown.X - pointMouseUp.X;
                int dy = pointMouseDown.Y - pointMouseUp.Y;

                int valueAux = 0;

                valueAux = this.HorizontalScroll.Value + dx;
                this.HorizontalScroll.Value = (valueAux > this.HorizontalScroll.Maximum) ?
                    this.HorizontalScroll.Maximum : ((valueAux < this.HorizontalScroll.Minimum) ? this.HorizontalScroll.Minimum : valueAux);
                this.PerformLayout();

                valueAux = this.VerticalScroll.Value + dy;
                this.VerticalScroll.Value = (valueAux > this.VerticalScroll.Maximum) ?
                    this.VerticalScroll.Maximum : ((valueAux < this.VerticalScroll.Minimum) ? this.VerticalScroll.Minimum : valueAux);
                this.PerformLayout();

                this.Cursor = Cursors.Default;
            }
        }

        private void DiagramView_MouseMove(object sender, MouseEventArgs e)
        {
            string str = "X = " + e.X + ", Y = " + e.Y;
            label_PosXY.Text = str;
        }

        #endregion Eventos de Mouse

        #region Evento KeyPress

        private void DiagramView_KeyPress(object sender, KeyPressEventArgs e)
        {
            if (ModifierKeys == Keys.Shift)
            {
                if (e.KeyChar == '+')
                    Zoom += 0.01;
                else if (e.KeyChar == '-')
                    Zoom -= 0.01;
            }
            Invalidate();
        }

        #endregion Evento KeyPress

    }
}
